unit skyboxes;

{*
SkyBox (6-side box with textures for displaying surrounding enviroment)

6 pictures are in:
data/image/envmap/[cube_map_name]/[up|down|left|right|front|back].png
}

interface

uses Classes, SysUtils, gl, glu, glut, textures, opengls, debugs;

type
  { TSkyBox }
  TSkyBox = class
  private
    FFront: TTexture;
    FBack: TTexture;
    FLeft: TTexture;
    FRight: TTexture;
    FUp: TTexture;
    FDown: TTexture;

  public
    Size: Longint;

    constructor Create(AName: string; ASize: Longint); virtual;
    destructor Destroy; override;

    procedure Show;
  end;

implementation

constructor TSkyBox.Create(AName: string; ASize: Longint);
begin
  Debug.Msg(dlBegin, 'TSkyBox.Create("' + AName + '", ' + FloatToStr(ASize) + ')');
  Size := ASize;
  FFront := TTexture.Create;
  FFront.Load('data/image/envmap/' + AName + '/front.png');
  Debug.Msg(dlDetail, '  front: ok');
  FBack := TTexture.Create;
  FBack.Load('data/image/envmap/' + AName + '/back.png');
  Debug.Msg(dlDetail, '  back: ok');
  FLeft := TTexture.Create;
  FLeft.Load('data/image/envmap/' + AName + '/left.png');
  Debug.Msg(dlDetail, '  left: ok');
  FRight := TTexture.Create;
  FRight.Load('data/image/envmap/' + AName + '/right.png');
  Debug.Msg(dlDetail, '  right: ok');
  FUp := TTexture.Create;
  FUp.Load('data/image/envmap/' + AName + '/up.png');
  Debug.Msg(dlDetail, '  up: ok');
  FDown := TTexture.Create;
  FDown.Load('data/image/envmap/' + AName + '/down.png');
  Debug.Msg(dlDetail, '  down: ok');
end;

destructor TSkyBox.Destroy;
begin
  FFront.Free;
  FBack.Free;
  FLeft.Free;
  FRight.Free;
  FUp.Free;
  FDown.Free;
  inherited;
end;

procedure TSkyBox.Show;
const
  c: Single = 0.002; // instead of this glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
var size2 : integer;
begin
  size2 := size div 2;
  // Show the cube map
  glDisable(GL_FOG);
  glEnable(GL_TEXTURE_2D);
  glDisable(GL_BLEND);
  glDisable(GL_LIGHTING);
  glEnable(GL_CULL_FACE);
  glDisable(GL_TEXTURE_GEN_S);
  glDisable(GL_TEXTURE_GEN_T);
  //glTranslatef(0, 0, 0);
//glDisable(GL_CULL_FACE); //-- kreslit obe strany ploch
  // front
  glBindTexture(GL_TEXTURE_2D, FFront.Id);
  glBegin(GL_QUADS);
  glTexCoord2d(1 - c, 0 + c);
  glVertex3i(size, size, -size);
  glTexCoord2d(0 + c, 0 + c);
  glVertex3i(-size, size, -size);
  glTexCoord2d(0 + c, 1 - c);
  glVertex3i(-size, -size, -size);
  glTexCoord2d(1 - c, 1 - c);
  glVertex3i(size, -size, -size);
  glEnd;
  // left
  glBindTexture(GL_TEXTURE_2D, FLeft.Id);
  glBegin(GL_QUADS);
  glTexCoord2d(0 + c, 0 + c);
  glVertex3i(-size, size, size);
  glTexCoord2d(0 + c, 1 - c);
  glVertex3i(-size, -size, size);
  glTexCoord2d(1 - c, 1 - c);
  glVertex3i(-size, -size, -size);
  glTexCoord2d(1 - c, 0 + c);
  glVertex3i(-size, size, -size);
  glEnd;
  // right
  glBindTexture(GL_TEXTURE_2D, FRight.Id);
  glBegin(GL_QUADS);
  glTexCoord2d(0 + c, 0 + c);
  glVertex3i(size, size, -size);
  glTexCoord2d(0 + c, 1 - c);
  glVertex3i(size, -size, -size);
  glTexCoord2d(1 - c, 1 - c);
  glVertex3i(size, -size, size);
  glTexCoord2d(1 - c, 0 + c);
  glVertex3i(size, size, size);
  glEnd;
  // back                   
  glBindTexture(GL_TEXTURE_2D, FBack.Id);
  glBegin(GL_QUADS);
  glTexCoord2d(0 + c, 1 - c);
  glVertex3i(size, -size, size);
  glTexCoord2d(1 - c, 1 - c);
  glVertex3i(-size, -size, size);
  glTexCoord2d(1 - c, 0 + c);
  glVertex3i(-size, size, size);
  glTexCoord2d(0 + c, 0 + c);
  glVertex3i(size, size, size);
  glEnd;
  // up
  glBindTexture(GL_TEXTURE_2D, FUp.Id);
  glBegin(GL_QUADS);
  glTexCoord2d(1 - c, 0 + c);
  glVertex3i(size, size, size);
  glTexCoord2d(0 + c, 0 + c);
  glVertex3i(-size, size, size);
  glTexCoord2d(0 + c, 1 - c);
  glVertex3i(-size, size, -size);
  glTexCoord2d(1 - c, 1 - c);
  glVertex3i(size, size, -size);
  glEnd;
  // down
  glBindTexture(GL_TEXTURE_2D, FDown.Id);
  glBegin(GL_QUADS);
  glTexCoord2d(1 - c, 0 + c);
  glVertex3i(size, -size, -size);
  glTexCoord2d(0 + c, 0 + c);
  glVertex3i(-size, -size, -size);
  glTexCoord2d(0 + c, 1 - c);
  glVertex3i(-size, -size, size);
  glTexCoord2d(1 - c, 1 - c);
  glVertex3i(size, -size, size);
  glEnd;
end;

initialization

finalization

end.
